package com.xhj.mybatis.mapping;

import com.xhj.mybatis.session.Configuration;
import com.xhj.mybatis.type.JdbcType;
import com.xhj.mybatis.type.TypeHandler;
import com.xhj.mybatis.type.TypeHandlerRegistry;

/**
 * ParameterMapping
 *
 * @author XJks
 * @description 参数映射类，用于描述 SQL 参数的各种属性
 */
public class ParameterMapping {

    /**
     * MyBatis 的全局配置对象
     */
    private Configuration configuration;

    /**
     * 参数对应的属性名
     */
    private String property;

    /**
     * Java 类型，默认为 Object.class
     */
    private Class<?> javaType = Object.class;

    /**
     * JDBC 类型
     */
    private JdbcType jdbcType;

    /**
     * 类型处理器，用于 Java 类型和 JDBC 类型之间的转换
     */
    private TypeHandler<?> typeHandler;

    private ParameterMapping() {
    }

    public static class Builder {

        private ParameterMapping parameterMapping = new ParameterMapping();

        public Builder(Configuration configuration, String property, Class<?> javaType) {
            parameterMapping.configuration = configuration;
            parameterMapping.property = property;
            parameterMapping.javaType = javaType;
        }

        public Builder javaType(Class<?> javaType) {
            parameterMapping.javaType = javaType;
            return this;
        }

        public Builder jdbcType(JdbcType jdbcType) {
            parameterMapping.jdbcType = jdbcType;
            return this;
        }

        public ParameterMapping build() {
            // 解析类型处理器
            resolveTypeHandler();
            // 校验参数合法性
            validate();
            return parameterMapping;
        }

        /**
         * 校验参数合法性
         */
        private void validate() {
            if (parameterMapping.typeHandler == null) {
                throw new IllegalStateException("Type handler was null on parameter mapping for property '"
                        + parameterMapping.property + "'. It was either not specified and/or could not be found for the javaType ("
                        + parameterMapping.javaType.getName() + ") : jdbcType (" + parameterMapping.jdbcType + ") combination.");
            }
        }

        /**
         * 解析类型处理器
         */
        private void resolveTypeHandler() {
            // 如果没有指定类型处理器且指定了 Java 类型，则从注册表中查找
            if (parameterMapping.typeHandler == null && parameterMapping.javaType != null) {
                Configuration configuration = parameterMapping.configuration;
                TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
                parameterMapping.typeHandler = typeHandlerRegistry.getTypeHandler(parameterMapping.javaType, parameterMapping.jdbcType);
            }
        }
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    public String getProperty() {
        return property;
    }

    public Class<?> getJavaType() {
        return javaType;
    }

    public JdbcType getJdbcType() {
        return jdbcType;
    }

    public TypeHandler<?> getTypeHandler() {
        return typeHandler;
    }
}

